/* 	testdominion.c
 *  Used to test full games of dominion
 *
 *	NOTE: for better readability, usibility and maintainability, interface should be edited so that
 *	all function can print to standard out or a file. this can easily be done with helper function.
 *	when time is available, these changes will be made.
 *
 *	Ryen Burzynski CS362 2/23/2014
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include "rngs.h"
#include "interface.h"
#include "dominion.h"

//global for helper functions
FILE * resultFile;

void _printState(struct gameState *game) {
  int numActions = game->numActions;
  int numCoins = game->coins;
  int numBuys = game->numBuys;
  int curPlayer = game->whoseTurn + 1;
  int phase = game->phase;
  char phaseName[MAX_STRING_LENGTH];
  phaseNumToName(phase,phaseName);
  fprintf(resultFile, "Player %d:\n%s phase\n%d actions\n%d coins\n%d buys\n\n", curPlayer, phaseName, numActions, numCoins, numBuys);
}

void _printSupply(struct gameState *game) {
  int cardNum, cardCost, cardCount;
  char name[MAX_STRING_LENGTH];
  fprintf(resultFile, "#   Card          Cost   Copies\n");
  for(cardNum = 0; cardNum < NUM_TOTAL_K_CARDS; cardNum++){
    cardCount = game->supplyCount[cardNum];
    if(cardCount == -1) continue;
    cardNumToName(cardNum, name);
    cardCost = getCardCost(cardNum);
    fprintf(resultFile, "%-2d  %-13s %-5d  %-5d", cardNum, name, cardCost, cardCount);
    fprintf(resultFile, "\n");
  }
  fprintf(resultFile, "\n");
}

void _printScores(struct gameState *game) {
  int playerNum, score[MAX_PLAYERS];
  int numPlayers = game->numPlayers;
  for(playerNum = 0; playerNum < numPlayers; playerNum++) {
    score[playerNum] = scoreFor(playerNum,game);
    fprintf(resultFile, "Player %d has a score of %d\n", playerNum +1, score[playerNum]);	//add 1 to playerNum for readability
  }
}

void _printKingdomCards(int king[NUM_K_CARDS]){
	int i;
	char buff[20];
	for(i = 0; i < NUM_K_CARDS; i++){
		cardNumToName(king[i], buff);
		fprintf(resultFile, "%s, ", buff);
	}
	fprintf(resultFile, "\n");
}


void advBotTurn(struct gameState *game, int k[NUM_K_CARDS]) {
	int coins = countHandCoins(whoseTurn(game), game);
	int curPlayer = (whoseTurn(game) + 1);
	int i, card, buy, tryBuy;
	char buff[20];
	
	//all prints should be in gameResults.out
	
	fprintf(resultFile, "*****************Player %d Turn*****************\n", curPlayer);
	_printState(game);
	//will add action phase
	//Action phase
	for(i = 0; i < game->handCount[whoseTurn(game)]; i++){
		card = game->hand[whoseTurn(game)][i];
		if((card == adventurer /*|| card == council_room*/ || card == smithy || card == village || card == great_hall) && game->numActions > 0){
			cardNumToName(card, buff);
			fprintf(resultFile, "Player %d plays %s card\n", curPlayer, buff);
			playCard(i, 0, 0, 0, game);
		/*}else if(card == feast && game->numActions > 0){
			cardNumToName(card, buff);
			fprintf(resultFile, "Player %d plays %s card\n", curPlayer, buff);
			playCard(i, k[rand() % 10], 0, 0, game);
		}else if(card == mine || card == remodel || card == baron && game->numActions > 0){
			//choice2 is irrelevant for remodel and baron
			cardNumToName(card, buff);
			fprintf(resultFile, "Player %d plays %s card\n", curPlayer, buff);
			playCard(i, (rand() % 5), k[NUM_K_CARDS], 0, game);*/
		}else if(card > gold && game->numActions > 0){
			//stopped at minion
			cardNumToName(card, buff);
			fprintf(resultFile, "Player %d plays %s card\n", curPlayer, buff);
			fprintf(resultFile, "no Action available for this card in tester\n");
			game->numActions--;
		}
	}
	
	//buy phase
	while(game->numBuys > 0){
		buy = (rand() % 4) + 1;
		if(buy < 3){
		
			if(coins >= PROVINCE_COST && supplyCount(province,game) > 0) {
				buyCard(province,game);
				fprintf(resultFile, "Player %d buys card Province\n\n", curPlayer);
			}else if(coins >= DUCHY_COST && supplyCount(duchy,game) > 0) {
				buyCard(duchy,game);
				fprintf(resultFile, "Player %d buys card Duchy\n\n", curPlayer);
			}else if(coins >= GOLD_COST && supplyCount(gold,game) > 0) {
				buyCard(gold,game);
				fprintf(resultFile, "Player %d buys card Gold\n\n", curPlayer);
			}else if(coins >= SILVER_COST && supplyCount(silver,game) > 0) {
				buyCard(silver,game);
				fprintf(resultFile, "Player %d buys card Silver\n\n", curPlayer);
			}else if(coins >= COPPER_COST && supplyCount(copper,game) > 0) {
				buyCard(copper,game);
				fprintf(resultFile, "Player %d buys card Copper\n\n", curPlayer);
			}else{
				fprintf(resultFile, "Player %d can't make a buy\n\n", curPlayer);
				game->numBuys = 0;
			}
			
		}else{
			tryBuy = k[rand() % 10];
			while(supplyCount(tryBuy,game) < 1){
				tryBuy = k[rand() % 10];
			}
			if(coins >= getCardCost(tryBuy)) {
				buyCard(tryBuy,game);
				cardNumToName(tryBuy, buff);
				fprintf(resultFile, "Player %d buys %s card\n\n", curPlayer, buff);
			}else if(coins >= COPPER_COST && supplyCount(copper,game) > 0) {
				buyCard(copper,game);
				fprintf(resultFile, "Player %d buys card Copper\n\n", curPlayer);
			}else{
				fprintf(resultFile, "Player %d can't make a buy\n\n", curPlayer);
				game->numBuys = 0;
			}
		}
		_printState(game);
		coins = countHandCoins(whoseTurn(game), game);
	}
		
	endTurn(game);
	
}


int main(int argc, char* argv[]) {
	struct gameState G;
	int k[NUM_K_CARDS];			//kingdom card array
	int seed = 1000;	//random seed
	int games = 10;		//games to be player
	int numPlayers, turnNum, player, i = 0;
		
	resultFile = fopen ("gameResults.out","w");
	
	//beginning prints
	printf("starting testdominion.c...\n");
	printf("number of games: %d\nseed: %d\n", games, seed);
	
	//beginning prints for gameResults.out
	fprintf(resultFile, "starting testdominion.c...\n");
	fprintf(resultFile, "number of games: %d\nseed: %d\n", games, seed);
	
	srand(seed);
	for(i = 1; i < (games + 1);i++){
		printf("\nGame %d start:\n", i);
		fprintf(resultFile, "\nGame %d start:\n", i);
		while(1){	//sets players from 2-4
			//printf("we're trying to set players\n");
			numPlayers = (rand() % 3) + 2;
			if(numPlayers < 5 && numPlayers > 1){
				break;
			}
			//printf("numPlayers = %d\n", numPlayers);
		}
		
		fprintf(resultFile, "numPlayers = %d\n", numPlayers);
		selectKingdomCards(rand(), k);			//pick random kingdom cards
		_printKingdomCards(k);					//print to resultFile
		initializeGame(numPlayers,k,1,&G);		
		while(!isGameOver(&G)){
			advBotTurn(&G, k);
		}
		//end game prints
		printf("Game %d is over.\n", i);
		fprintf(resultFile, "Game %d is over.\n\n", i);
		_printSupply(&G);						//supply count to resultFile
		_printScores(&G);						//player scores to resultFile
		
	}

	printf("All tests completed successfully!\n\n");
		
	return 0;
}
